package org.hepeng.workx.util.timer;


import lombok.Builder;
import lombok.Data;
import rx.Observable;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author he peng
 */
public class TimeoutCaller {

    public static <R> R call(Function<R> function , long timeout, TimeUnit timeUnit) {
        CallResult.CallResultBuilder resultBuilder = CallResult.builder();
        Observable.defer(() -> Observable.just(function.call()))
                .timeout(timeout , timeUnit)
                .subscribe(r -> resultBuilder.result(r) , t -> resultBuilder.throwable(t));
        if (Objects.nonNull(resultBuilder.throwable)) {
            if (RuntimeException.class.isAssignableFrom(resultBuilder.throwable.getClass())) {
                throw (RuntimeException) resultBuilder.throwable;
            }
            throw new RuntimeException(resultBuilder.throwable);
        }
        return (R) resultBuilder.result;
    }

    @Data
    @Builder
    private static class CallResult {
        private Object result;
        private Throwable throwable;
    }
}
